<?php
namespace app\service;

use app\admin\model\shop\Order;
use app\admin\model\User;
use app\admin\model\rebate\Batches as RebateBatch;
use app\admin\model\RebatePeriod;
use app\admin\model\DividendPool;
use app\admin\model\rebate\Logs as FaRebateLog;
use \think\Db;

class RebateService
{
    // 触发返利（自动/手动）(暂时不用)
    public function triggerRebate($isManual = false, $customRatio = null)
    {
        // 1. 计算触发条件
        // 触发条件为 获取fa_dividend_pool表记录 资金池的15% 和 期数
        $DividendPool = new DividendPool;
        $DividendPoolFirst = $DividendPool->getFirst();
        list($nextPeriod, $requiredProfit) = $this->getNextPeriod($DividendPoolFirst);

        // 当前期利润
        $currentProfit = $DividendPoolFirst->newprofit;

        if (!$isManual && $currentProfit < $requiredProfit) {
            return ['status' => 'fail', 'msg' => '利润不足'];
        }

        // 2. 查询未完成订单
        $unfinishedOrders = Order::where('is_completed', 0)
                                ->where('current_period', '<', 50)
                                ->where('data_type',1)
                                ->select();

        // 3. 计算总应返积分（手动触发时支持按比例返利）
        $originalTotalScheduled = 0; // 原计划积分总数
        $actualTotalScheduled = 0;   // 实际返利积分总数
        $profitRatio = 1; // 默认100%返利
        
        // 如果是手动触发，检查是否需要按比例返利
        if ($isManual) {
            // 如果提供了自定义比例且不为空也不为0，使用自定义比例
            if ($customRatio !== null && $customRatio != 0) {
                $profitRatio = $customRatio / 100;
                $profitRatio = min(1, max(0, $profitRatio)); // 限制在0-1之间
                \think\Log::info('[triggerRebate] 手动触发按自定义比例返利: 指定比例=' . $customRatio . '%, 实际比例=' . ($profitRatio * 100) . '%');
            }
            // 如果自定义比例为空或者为0，或者利润不足，计算建议比例
            else if ($currentProfit < $requiredProfit && $requiredProfit > 0) {
                $profitRatio = $currentProfit / $requiredProfit;
                $profitRatio = min(1, max(0, $profitRatio)); // 限制在0-1之间
                \think\Log::info('[triggerRebate] 手动触发按计算比例返利: 当前利润=' . $currentProfit . ', 需要利润=' . $requiredProfit . ', 返利比例=' . ($profitRatio * 100) . '%');
            }
        }

        
        foreach ($unfinishedOrders as $order) {
            $period = $order->current_period + 1;
            $originalPoints = $this->calculateOrderPoints($order, $period);
            $actualPoints = floor($originalPoints * $profitRatio);
            
            $originalTotalScheduled += $originalPoints; // 累计原计划积分
            $actualTotalScheduled += $actualPoints;     // 累计实际积分
        }
        
        // 保存每个订单的积分计算结果，避免后续重复计算导致不一致
        $orderPointsData = [];
        foreach ($unfinishedOrders as $order) {
            $period = $order->current_period + 1;
            $originalPoints = $this->calculateOrderPoints($order, $period);
            $actualPoints = floor($originalPoints * $profitRatio);
            
            $orderPointsData[$order->id] = [
                'period' => $period,
                'scheduled_points' => $originalPoints,
                'actual_points' => $actualPoints
            ];
        }

        // 4. 插入批次记录
        // 触发前分红池金额 资金池等金额
        $dividendBefore = (new DividendPool())->getBalance() ?: 0;
        $newprofit_before = $DividendPoolFirst ? $DividendPoolFirst->newprofit : 0;
        $newprofit_after = 0;
        $zijin_pool_before = $DividendPoolFirst ? $DividendPoolFirst->zijin_pool : 0;
        $zijin_pool_after = $zijin_pool_before + $newprofit_before;

        
        // 计算触发时商城所有订单总金额
        $totalOrderAmount = Order::where('data_type', 1)->sum('payamount') ?: 0;
        
        // 记录总金额计算日志
        \think\Log::info('[triggerRebate] 触发时计算总订单金额: ' . $totalOrderAmount . ', 利润: ' . $currentProfit . ' (利润率: 20%)');
        
        // 获取受影响用户数量
        $userIds = [];
        foreach ($unfinishedOrders as $order) {
            $userIds[] = $order->user_id;
        }
        $uniqueUsers = array_unique($userIds);
        
        $batchData = [
            'total_profit' => '',
            // 'principal_profit_sum' => $this->calculatePrincipalSum($Batch, $currentProfit),
            'principal_profit_sum' => '',
            'period' => $nextPeriod, // 记录返利期数（第1期到第50期）
            'is_manual' => $isManual,
            'scheduled_total_points' => $originalTotalScheduled, // 原计划积分总数
            'actual_total_points' => 0, // 初始为0，后续更新
            'required_profit' => $requiredProfit,
            'users_affected' => count($uniqueUsers),
            'dividend_before' => $dividendBefore,
            'dividend_after' => 0, // 初始为0，后续更新
            'zijin_pool_before' => $zijin_pool_before,
            'zijin_pool_after' => $zijin_pool_after,
            'newprofit_before' => $newprofit_before,
            'newprofit_after' => $newprofit_after,
            'status' => 'processing', // 初始状态为处理中
            'triggered_at' => date('Y-m-d H:i:s'), // 触发时间使用datetime格式
            'total_money' => $totalOrderAmount, // 触发时商城所有订单总金额
        ];
        $batchId = RebateBatch::createBatch($batchData)->id;

        // 5. 校验分红池余额是否够用（使用实际积分）
        $currentBalance = (new DividendPool())->getBalance() ?: 0;
        if ($currentBalance < $actualTotalScheduled) {
            $this->updateBatchFailed($batchId);
            return ['status' => 'fail', 'msg' => '分红池不足'];
        }

        // 6. 扣除分红池（使用实际积分）更新资金池 新增金额 期数
        (new DividendPool())->chufa_deduct(
            $actualTotalScheduled, 
            null, 
            $batchId, 
            '返利批次支出，批次ID：' . $batchId . '，返利期数：第' . $nextPeriod . '期，积分总数：' . $actualTotalScheduled,
            $zijin_pool_after
        );
        // 更新订单返利期数
        $this->updateOrderPeriods($unfinishedOrders);
        $dividendAfter = (new DividendPool())->getBalance() ?: 0;

        // 7. 记录订单级日志（传入已计算好的积分数据）
        $this->recordOrderLogs($unfinishedOrders, $batchId, $isManual, $orderPointsData);

        // 8. 更新批次实际数据
        RebateBatch::where('id', $batchId)
            ->update([
                'actual_total_points' => $actualTotalScheduled, // 实际返利积分总数
                'dividend_after' => $dividendAfter,
                'status' => 'completed', // 标记为完成
                'completed_at' => date('Y-m-d H:i:s'), // 完成时间使用datetime格式
            ]);

        // 9. 转化积分到权益值（传入已计算好的积分数据）
        // 注意：这里使用原计划积分数量来扣除用户积分，但实际转化到权益值的是按比例计算后的实际积分
        $this->convertEquityValues($unfinishedOrders, $orderPointsData, $originalTotalScheduled);

        // 构建返回消息
        $message = [
            'status' => 'success', 
            'batch_id' => $batchId,
            'period' => $nextPeriod, // 添加返利期数信息
        ];
        
        // 如果是手动触发且按比例返利，添加比例信息
        if ($isManual) {
            if ($customRatio !== null && $customRatio != 0) {
                $message['profit_ratio'] = $customRatio . '%';
                $message['msg'] = '手动触发成功，按' . $message['profit_ratio'] . '比例返利';
            } else if ($profitRatio < 1) {
                $message['profit_ratio'] = round($profitRatio * 100, 2) . '%';
                $message['msg'] = '手动触发成功，按' . $message['profit_ratio'] . '比例返利';
            } else {
                $message['msg'] = '手动触发成功，按100%比例返利';
            }
        }
        
        return $message;
    }

    public function triggerRebateGuding($isManual = false, $customRatio = null)
    {
        // 1. 计算触发条件
        // 触发条件为 获取fa_dividend_pool表记录 资金池的15% 和 期数
        $DividendPool = new DividendPool;
        $DividendPoolFirst = $DividendPool->getFirst();
        list($nextPeriod, $requiredProfit) = $this->getNextPeriod($DividendPoolFirst);

        // 当前期利润
        $currentProfit = $DividendPoolFirst->newprofit;

        // if (!$isManual && $currentProfit < $requiredProfit) {
        //     return ['status' => 'fail', 'msg' => '利润不足'];
        // }

        // 2. 查询未完成订单
        $unfinishedOrders = Order::where(function ($query) {
                                    $query->where('shoppingIntegral', '>', 0)
                                          ->whereOr('couponIntegral', '>', 0);
                                })
                                ->where('data_type', 1)
                                ->select();


        // 3. 计算总应返积分（手动触发时支持按比例返利）
        $originalTotalScheduled = 0; // 原计划积分总数
        $actualTotalScheduled = 0;   // 实际返利积分总数
        $profitRatio = 1; // 默认100%返利
        
        // 如果是手动触发，检查是否需要按比例返利
        // if ($isManual) {
        //     // 如果提供了自定义比例且不为空也不为0，使用自定义比例
        //     if ($customRatio !== null && $customRatio != 0) {
        //         $profitRatio = $customRatio / 100;
        //         $profitRatio = min(1, max(0, $profitRatio)); // 限制在0-1之间
        //         \think\Log::info('[triggerRebate] 手动触发按自定义比例返利: 指定比例=' . $customRatio . '%, 实际比例=' . ($profitRatio * 100) . '%');
        //     }
        //     // 如果自定义比例为空或者为0，或者利润不足，计算建议比例
        //     else if ($currentProfit < $requiredProfit && $requiredProfit > 0) {
        //         $profitRatio = $currentProfit / $requiredProfit;
        //         $profitRatio = min(1, max(0, $profitRatio)); // 限制在0-1之间
        //         \think\Log::info('[triggerRebate] 手动触发按计算比例返利: 当前利润=' . $currentProfit . ', 需要利润=' . $requiredProfit . ', 返利比例=' . ($profitRatio * 100) . '%');
        //     }
        // }

        // 返利固定值
        $shopping_to_value = Db::name('config')->where('name','shopping_to_value')->value('value');
        $coupon_to_value = Db::name('config')->where('name','coupon_to_value')->value('value');


        // 原来是按期，现改为按固定值
        foreach ($unfinishedOrders as $order) {
            // $period = $order->current_period + 1;
            // $originalPoints = $this->calculateOrderPoints($order, $period);

            if($order->shoppingIntegral>0){
                $orderAmount = $order->payamount ?: 0;
                $calculatedPoints = ($orderAmount / 10000) * $shopping_to_value;
                $originalPoints = floor($calculatedPoints);
            }else{
                $orderAmount = $order->payamount ?: 0;
                $calculatedPoints = ($orderAmount / 10000) * $coupon_to_value;
                $originalPoints = floor($calculatedPoints);
            }

            $originalTotalScheduled += $originalPoints; // 累计原计划积分
            $actualTotalScheduled += $originalPoints;     // 累计实际积分
        }
        
        // 保存每个订单的积分计算结果，避免后续重复计算导致不一致
        $orderPointsData = [];
        foreach ($unfinishedOrders as $order) {
            // $period = $order->current_period + 1;
            // $originalPoints = $this->calculateOrderPoints($order, $period);
            // $actualPoints = floor($originalPoints * $profitRatio);

            if($order->shoppingIntegral>0){
                $orderAmount = $order->payamount ?: 0;
                $calculatedPoints = ($orderAmount / 10000) * $shopping_to_value;
                $originalPoints = floor($calculatedPoints);
            }else{
                $orderAmount = $order->payamount ?: 0;
                $calculatedPoints = ($orderAmount / 10000) * $coupon_to_value;
                $originalPoints = floor($calculatedPoints);
            }
            
            $orderPointsData[$order->id] = [
                'period' => '',
                'scheduled_points' => $originalPoints,
                'actual_points' => $originalPoints
            ];
        }
        // 更新订单积分值（扣除购物积分和消费券）
        $this->deductOrderPoints($unfinishedOrders, $shopping_to_value, $coupon_to_value);
        
        // 4. 插入批次记录
        // 触发前分红池金额 资金池等金额
        $dividendBefore = (new DividendPool())->getBalance() ?: 0;
        $newprofit_before = $DividendPoolFirst ? $DividendPoolFirst->newprofit : 0;
        $newprofit_after = 0;
        $zijin_pool_before = $DividendPoolFirst ? $DividendPoolFirst->zijin_pool : 0;
        $zijin_pool_after = $zijin_pool_before + $newprofit_before;

        
        // 计算触发时商城所有订单总金额
        $totalOrderAmount = Order::where('data_type', 1)->sum('payamount') ?: 0;
        
        // 记录总金额计算日志
        \think\Log::info('[每天固定返利]');
        
        // 获取受影响用户数量
        $userIds = [];
        foreach ($unfinishedOrders as $order) {
            $userIds[] = $order->user_id;
        }
        $uniqueUsers = array_unique($userIds);
        
        $batchData = [
            'total_profit' => '',
            // 'principal_profit_sum' => $this->calculatePrincipalSum($Batch, $currentProfit),
            'principal_profit_sum' => '',
            'period' => '', // 记录返利期数
            'is_manual' => $isManual,
            'scheduled_total_points' => $originalTotalScheduled, // 原计划积分总数
            'actual_total_points' => 0, // 初始为0，后续更新
            'required_profit' => $requiredProfit,
            'users_affected' => count($uniqueUsers),
            'dividend_before' => $dividendBefore,
            'dividend_after' => 0, // 初始为0，后续更新
            'zijin_pool_before' => $zijin_pool_before,
            'zijin_pool_after' => $zijin_pool_after,
            'newprofit_before' => $newprofit_before,
            'newprofit_after' => $newprofit_after,
            'status' => 'processing', // 初始状态为处理中
            'triggered_at' => date('Y-m-d H:i:s'), // 触发时间使用datetime格式
            'total_money' => $totalOrderAmount, // 触发时商城所有订单总金额
        ];
        $batchId = RebateBatch::createBatch($batchData)->id;

        // 5. 校验分红池余额是否够用（使用实际积分）
        // $currentBalance = (new DividendPool())->getBalance() ?: 0;
        // if ($currentBalance < $actualTotalScheduled) {
        //     $this->updateBatchFailed($batchId);
        //     return ['status' => 'fail', 'msg' => '分红池不足'];
        // }

        // 6. 扣除分红池（使用实际积分）更新资金池 新增金额
        (new DividendPool())->chufa_deduct(
            $actualTotalScheduled, 
            null, 
            $batchId, 
            '返利批次支出，批次ID：' . $batchId . '，' . '，积分总数：' . $actualTotalScheduled,
            $zijin_pool_after
        );
        

        $dividendAfter = (new DividendPool())->getBalance() ?: 0;

        // 7. 记录订单级日志（传入已计算好的积分数据）
        $this->recordOrderLogs($unfinishedOrders, $batchId, $isManual, $orderPointsData);

        // 8. 更新批次实际数据
        RebateBatch::where('id', $batchId)
            ->update([
                'actual_total_points' => $actualTotalScheduled, // 实际返利积分总数
                'dividend_after' => $dividendAfter,
                'status' => 'completed', // 标记为完成
                'completed_at' => date('Y-m-d H:i:s'), // 完成时间使用datetime格式
            ]);

        // 9. 转化积分到权益值（传入已计算好的积分数据）
        $this->convertEquityValues($unfinishedOrders, $orderPointsData, $originalTotalScheduled);

        // 构建返回消息
        $message = [
            'status' => 'success', 
            'batch_id' => $batchId,
            'period' => '', // 添加返利期数信息
        ];
        
        // 如果是手动触发且按比例返利，添加比例信息
        // if ($isManual) {
        //     if ($customRatio !== null && $customRatio != 0) {
        //         $message['profit_ratio'] = $customRatio . '%';
        //         $message['msg'] = '手动触发成功，按' . $message['profit_ratio'] . '比例返利';
        //     } else if ($profitRatio < 1) {
        //         $message['profit_ratio'] = round($profitRatio * 100, 2) . '%';
        //         $message['msg'] = '手动触发成功，按' . $message['profit_ratio'] . '比例返利';
        //     } else {
        //         $message['msg'] = '手动触发成功，按100%比例返利';
        //     }
        // }
        
        return $message;
    }


    // 触发返利，固定返利 (废弃 不用了)
    public function triggerRebateGuding_feiqi($isManual = false, $customRatio = null)
    {
        $DividendPool = new DividendPool;
        $DividendPoolFirst = $DividendPool->getFirst();

        // 插入批次记录
        // 触发前分红池金额 资金池等金额
        $dividendBefore = (new DividendPool())->getBalance() ?: 0;
        $newprofit_before = $DividendPoolFirst ? $DividendPoolFirst->newprofit : 0;
        $newprofit_after = 0;
        $zijin_pool_before = $DividendPoolFirst ? $DividendPoolFirst->zijin_pool : 0;
        $zijin_pool_after = $zijin_pool_before + $newprofit_before;

        
        // 计算触发时商城所有订单总金额
        $totalOrderAmount = Order::where('data_type', 1)->sum('payamount') ?: 0;
        
        // 记录日志
        \think\Log::info('');
        
        $batchData = [
            'total_profit' => '',
            // 'principal_profit_sum' => $this->calculatePrincipalSum($Batch, $currentProfit),
            'principal_profit_sum' => '',
            'period' => '', 
            'is_manual' => $isManual,
            'scheduled_total_points' => '', // 原计划积分总数
            'actual_total_points' => 0, // 初始为0，后续更新
            'required_profit' => '',
            'users_affected' => '',
            'dividend_before' => $dividendBefore,
            'dividend_after' => 0, // 初始为0，后续更新
            'zijin_pool_before' => $zijin_pool_before,
            'zijin_pool_after' => $zijin_pool_after,
            'newprofit_before' => $newprofit_before,
            'newprofit_after' => $newprofit_after,
            'status' => 'processing', // 初始状态为处理中
            'triggered_at' => date('Y-m-d H:i:s'), // 触发时间使用datetime格式
            'total_money' => $totalOrderAmount, // 触发时商城所有订单总金额
        ];
        $batchId = RebateBatch::createBatch($batchData)->id;

        // 更新批次实际数据
        RebateBatch::where('id', $batchId)
            ->update([
                'actual_total_points' => '',
                'dividend_after' => '',
                'status' => 'completed', // 标记为完成
                'completed_at' => date('Y-m-d H:i:s'), // 完成时间使用datetime格式
            ]);

        // 转化积分到权益值（传入已计算好的积分数据）
        $shopping_to_value = Db::name('config')->where('name','shopping_to_value')->value('value');
        $coupon_to_value = Db::name('config')->where('name','coupon_to_value')->value('value');
        $this->convertEquityValuesGuding($shopping_to_value, $coupon_to_value);

        // 构建返回消息
        $message = [
            'status' => 'success', 
            'batch_id' => $batchId,
            'period' => '', // 添加返利期数信息
        ];
        
        return $message;
    }


    /**
     * 计算当前总利润（所有订单利润之和）
     */
    public function calculateTotalProfit()
    {
        // 订单表中 总金额，利润率为20%
        $totalProfit = Order::where('data_type', 1)->sum('payamount') * 0.2;

        return $totalProfit;
    }


    /**
     * 计算下一批次的本金利润和(废弃)
     */
    // private function calculatePrincipalSum($lastBatch, $currentProfit)
    // {
    //     if ($lastBatch) {
    //         // 存在上一批次，累加本金利润和
    //         return $lastBatch['principal_profit_sum'] + $currentProfit;
    //     } else {
    //         // 无历史批次，初始本金为10万
    //         return 100000 + $currentProfit;
    //     }
    // }

    /**
     * 标记批次触发失败
     */
    private function updateBatchFailed($batchId)
    {
        RebateBatch::where('id', $batchId)
            ->update([
                'actual_total_points' => 0,
                'dividend_after' => (new DividendPool())->getBalance() ?: 0,
                'status' => 'failed', // 标记为失败
                'completed_at' => date('Y-m-d H:i:s'), // 完成时间使用datetime格式
            ]);
    }

    /**
     * 计算下一期返利期数及触发条件
     */
    public function getNextPeriod($Batch)
    {
        // 使用period字段计算下一期数（第1期到第50期）
        if ($Batch) {
            $nextPeriod = $Batch->period + 1;
            $requiredProfit = $Batch->zijin_pool * 0.15;
        } else {
            // 如果没有批次记录，默认从第1期开始
            $nextPeriod = 1;
            // 如果没有分红池记录，设置一个默认的触发条件
            $dividendPool = new DividendPool();
            $dividendPoolFirst = $dividendPool->getFirst();
            $zijinPool = $dividendPoolFirst ? $dividendPoolFirst->zijin_pool : 0;
            $requiredProfit = $zijinPool * 0.15;
        }
    
        return [$nextPeriod, $requiredProfit];
    }

    /**
     * 更新订单返利期数
     */
    private function updateOrderPeriods($orders)
    {
        foreach ($orders as $order) {
            $order->nextPeriod();
            if ($order->current_period >= 50) {
                $order->completeRebate();
            }
        }
    }

    /**
     * 记录订单返利日志
     * @param array $orders 订单列表
     * @param int $batchId 批次ID
     * @param bool $isManual 是否手动触发
     * @param array $orderPointsData 预计算的订单积分数据
     */
    private function recordOrderLogs($orders, $batchId, $isManual, $orderPointsData)
    {
        foreach ($orders as $order) {
            // 使用预计算的积分数据，确保一致性
            $pointsData = $orderPointsData[$order->id];
            $period = $pointsData['period'];
            $scheduledPoints = $pointsData['scheduled_points'];
            $actualPoints = $pointsData['actual_points'];
            
            // 记录详细的计算过程
            $ratio = $actualPoints > 0 ? ($actualPoints / $scheduledPoints) * 100 : 0;
            \think\Log::info('[recordOrderLogs] 订单ID: ' . $order->id . ', 第' . $period . '期返利: 原计划积分=' . $scheduledPoints . ', 实际积分=' . $actualPoints . ', 比例=' . round($ratio, 2) . '%');
            
            FaRebateLog::logRebate(
                $batchId,
                $order->id,
                $order->user_id,
                $period,
                $scheduledPoints, // 使用预计算的原计划积分
                $actualPoints,    // 使用预计算的实际返利积分
                $isManual
            );
        }
    }

    /**
     * 转化积分到权益值(按订单期数)
     * @param array $orders 订单列表
     * @param array $orderPointsData 预计算的订单积分数据
     * @param int $originalTotalScheduled 原计划积分总数（用于用户积分扣除）
     */
    private function convertEquityValues($orders, $orderPointsData, $originalTotalScheduled)
    {
        $userMap = [];
        $actualTotal = 0; // 实际总积分
        
        foreach ($orders as $order) {
            $userId = $order->user_id;
            // 使用预计算的积分数据
            $pointsData = $orderPointsData[$order->id];
            $originalPoints = $pointsData['scheduled_points']; // 原计划积分
            $actualPoints = $pointsData['actual_points'];      // 实际积分
            
            if (!isset($userMap[$userId])) {
                $userMap[$userId] = [
                    'original' => 0,  // 原计划积分
                    'actual' => 0,    // 实际积分
                ];
            }
            
            $userMap[$userId]['original'] += $originalPoints;
            $userMap[$userId]['actual'] += $actualPoints;
            $actualTotal += $actualPoints;
        }
        
        // 记录转化信息
        \think\Log::info('[convertEquityValues] 原计划积分总数: ' . $originalTotalScheduled . ', 实际积分总数: ' . $actualTotal);

        foreach ($userMap as $userId => $data) {
            $user = User::find($userId);
            $originalUserPoints = $data['original']; // 用户原计划积分
            $actualUserPoints = $data['actual'];     // 用户实际积分
            
            \think\Log::info('[convertEquityValues] 用户ID: ' . $userId . ', 原计划积分: ' . $originalUserPoints . ', 实际积分: ' . $actualUserPoints);
            
            // 扣除用户原计划积分数量，但实际转化到权益值的是按比例计算后的实际积分
            $shoppingAvailable = $user->shopping_integral;
            $couponAvailable = $user->coupon_integral;
            
            // 检查用户是否有足够的积分
            if ($shoppingAvailable + $couponAvailable >= $originalUserPoints) {
                // 扣除用户原计划积分数量
                if ($shoppingAvailable >= $originalUserPoints) {
                    // 先扣除购物积分
                    $user->convertEquity($originalUserPoints, 0, $actualUserPoints);
                } else {
                    $remain = $originalUserPoints - $shoppingAvailable;
                    $user->convertEquity($shoppingAvailable, min($remain, $couponAvailable), $actualUserPoints);
                }
            } else {
                // 用户积分不足，按比例扣除
                $ratio = ($shoppingAvailable + $couponAvailable) / $originalUserPoints;
                $actualConverted = floor($actualUserPoints * $ratio);
                
                if ($shoppingAvailable >= ($shoppingAvailable + $couponAvailable)) {
                    $user->convertEquity($shoppingAvailable + $couponAvailable, 0, $actualConverted);
                } else {
                    $remain = ($shoppingAvailable + $couponAvailable) - $shoppingAvailable;
                    $user->convertEquity($shoppingAvailable, min($remain, $couponAvailable), $actualConverted);
                }
            }
        }
    }

    /**
     * 转化积分到权益值(按固定值返)
     * shopping_to_value 扣除购物积分返权益值数量
     * coupon_to_value 扣消费券返权益值数量
     */
    private function convertEquityValuesGuding($shopping_to_value, $coupon_to_value)
    {
        // 查询user表 shopping_integral字段或者coupon_integral字段大于0的用户
        $users = Db::name('user')
            ->field('id,shopping_integral,coupon_integral')
            ->where('shopping_integral', '>', 0)
            ->whereOr('coupon_integral', '>', 0)
            ->select();

        // 记录转化信息
        \think\Log::info('[convertEquityValuesGuding] 开始转化积分到权益值, shopping_to_value: ' . $shopping_to_value . ', coupon_to_value: ' . $coupon_to_value);

        // 统计总共扣除的积分和返还的权益值
        $totalShoppingDeducted = 0;
        $totalCouponDeducted = 0;
        $totalEquityReturned = 0;

        foreach ($users as $userData) {
            $userId = $userData['id'];
            $user = User::find($userId);
            
            \think\Log::info('[convertEquityValuesGuding] 处理用户ID: ' . $userId . ', 购物积分: ' . $user->shopping_integral . ', 消费券积分: ' . $user->coupon_integral);
            
            // 先检查是否有购物积分，如果有则优先扣除购物积分
            $shoppingAvailable = $user->shopping_integral;
            $couponAvailable = $user->coupon_integral;
            
            // 如果有购物积分
            if ($shoppingAvailable > 0) {
                // 购物积分够扣除的，就不扣除消费券了
                if ($shoppingAvailable >= $shopping_to_value) {
                    \think\Log::info('[convertEquityValuesGuding] 用户ID: ' . $userId . ', 扣除购物积分: ' . $shopping_to_value);
                    $user->convertEquity($shopping_to_value, 0, $shopping_to_value); // 扣除多少金额 返多少到权益值
                    $totalShoppingDeducted += $shopping_to_value;
                    $totalEquityReturned += $shopping_to_value;
                } else {
                    // 购物积分不够，先扣完购物积分
                    \think\Log::info('[convertEquityValuesGuding] 用户ID: ' . $userId . ', 扣除购物积分: ' . $shoppingAvailable);
                    $user->convertEquity($shoppingAvailable, 0, $shoppingAvailable);
                    $totalShoppingDeducted += $shoppingAvailable;
                    $totalEquityReturned += $shoppingAvailable;
                    
                    // 再扣消费券（如果还有需要扣除的）
                    $remainingValue = $shopping_to_value - $shoppingAvailable;
                    $couponToDeduct = min($couponAvailable, $remainingValue, $coupon_to_value);
                    if ($couponToDeduct > 0) {
                        \think\Log::info('[convertEquityValuesGuding] 用户ID: ' . $userId . ', 扣除消费券积分: ' . $couponToDeduct);
                        $user->convertEquity(0, $couponToDeduct, $couponToDeduct); // 扣除多少金额 返多少到权益值
                        $totalCouponDeducted += $couponToDeduct;
                        $totalEquityReturned += $couponToDeduct;
                    }
                }
            } else {
                // 没有购物积分了，直接扣除消费券
                $couponToDeduct = min($couponAvailable, $coupon_to_value);
                if ($couponToDeduct > 0) {
                    \think\Log::info('[convertEquityValuesGuding] 用户ID: ' . $userId . ', 扣除消费券积分: ' . $couponToDeduct);
                    $user->convertEquity(0, $couponToDeduct, $couponToDeduct); // 扣除多少金额 返多少到权益值
                    $totalCouponDeducted += $couponToDeduct;
                    $totalEquityReturned += $couponToDeduct;
                }
            }
        }
        
        // 记录总的统计信息
        \think\Log::info('[convertEquityValuesGuding] 积分转化完成统计: 总共扣除购物积分: ' . $totalShoppingDeducted . ', 总共扣除消费券积分: ' . $totalCouponDeducted . ', 总共返还权益值: ' . $totalEquityReturned);
    }

    /**
     * 扣除订单积分值
     * @param array $orders 订单列表
     * @param int $shopping_to_value 购物积分扣除值
     * @param int $coupon_to_value 消费券扣除值
     */
    private function deductOrderPoints($orders, $shopping_to_value, $coupon_to_value)
    {
        \think\Log::info('[deductOrderPoints] 开始扣除订单积分');
        
        foreach ($orders as $order) {
            // 获取订单当前的积分值
            $currentShoppingIntegral = $order->shoppingIntegral;
            $currentCouponIntegral = $order->couponIntegral;

            $orderAmount = $order->payamount ?: 0;
            $shopping_to_value = ($orderAmount / 10000) * $shopping_to_value;
            $coupon_to_value = ($orderAmount / 10000) * $coupon_to_value;
            
            \think\Log::info('[deductOrderPoints] 订单ID: ' . $order->id . ', 当前购物积分: ' . $currentShoppingIntegral . ', 当前消费券积分: ' . $currentCouponIntegral);
            
            // 如果有购物积分，优先扣除购物积分
            if ($currentShoppingIntegral > 0) {
                // 购物积分够扣除的，就不扣除消费券了
                if ($currentShoppingIntegral >= $shopping_to_value) {
                    $order->shoppingIntegral = $currentShoppingIntegral - $shopping_to_value;
                    \think\Log::info('[deductOrderPoints] 订单ID: ' . $order->id . ', 扣除购物积分: ' . $shopping_to_value . ', 剩余购物积分: ' . $order->shoppingIntegral);
                } else {
                    // 购物积分不够，先扣完购物积分
                    $order->shoppingIntegral = 0;
                    \think\Log::info('[deductOrderPoints] 订单ID: ' . $order->id . ', 扣除购物积分: ' . $currentShoppingIntegral . ', 购物积分已扣完');
                    
                    // 再扣消费券（如果还有需要扣除的）
                    $remainingValue = $shopping_to_value - $currentShoppingIntegral;
                    $couponToDeduct = min($currentCouponIntegral, $remainingValue, $coupon_to_value);
                    $order->couponIntegral = $currentCouponIntegral - $couponToDeduct;
                    \think\Log::info('[deductOrderPoints] 订单ID: ' . $order->id . ', 扣除消费券积分: ' . $couponToDeduct . ', 剩余消费券积分: ' . $order->couponIntegral);
                }
            } else {
                // 没有购物积分了，直接扣除消费券
                $couponToDeduct = min($currentCouponIntegral, $coupon_to_value);
                $order->couponIntegral = $currentCouponIntegral - $couponToDeduct;
                \think\Log::info('[deductOrderPoints] 订单ID: ' . $order->id . ', 扣除消费券积分: ' . $couponToDeduct . ', 剩余消费券积分: ' . $order->couponIntegral);
            }
            
            // 保存订单积分值的更新
            $order->save();
        }
        
        \think\Log::info('[deductOrderPoints] 订单积分扣除完成');
    }

    /**
     * 根据订单金额和期数计算返利积分
     * 
     * @param object $order 订单对象
     * @param int $period 返利期数
     * @return int 计算后的积分数量
     */
    private function calculateOrderPoints($order, $period)
    {
        $basePeriodPoints = RebatePeriod::getPointsByPeriod($period);
        $orderAmount = $order->payamount ?: 0;
        
        // 计算公式：订单金额/10000*本期积分数量
        $calculatedPoints = ($orderAmount / 10000) * $basePeriodPoints;
        
        // 记录调试日志
        \think\Log::info('[calculateOrderPoints] 订单ID: ' . $order->id . ', 订单金额: ' . $orderAmount . ', 第' . $period . '期基础积分: ' . $basePeriodPoints . ', 计算后积分: ' . $calculatedPoints);
        
        return floor($calculatedPoints); // 向下取整
    }

}